/**
 * datagrid表头拖动 js 事件 末尾增加.datagrid("columnMoving")
 */
$.extend($.fn.datagrid.methods, {
    columnMoving: function (jq) {
        return jq.each(function () {
            var target = this;
            var cells = $(this).datagrid('getPanel').find('div.datagrid-header td[field]');
            cells.draggable({
                revert: true,
                cursor: 'pointer',
                edge: 5,
                proxy: function (source) {
                    var p = $('<div class="tree-node-proxy tree-dnd-no" />').appendTo('body');
                    p.html($(source).text());
                    p.hide();
                    return p;
                },
                onBeforeDrag: function (e) {
                    e.data.startLeft = $(this).offset().left;
                    e.data.startTop = $(this).offset().top;
                },
                onStartDrag: function () {
                    $(this).draggable('proxy').css({
                        left: -10000,
                        top: -10000
                    });
                },
                onDrag: function (e) {
                    $(this).draggable('proxy').show().css({
                        left: e.pageX + 15,
                        top: e.pageY + 15
                    });
                    return false;
                }
            }).droppable({
                accept: 'td[field]',
                onDragOver: function (e, source) {
                    $(source).draggable('proxy').removeClass('tree-dnd-no').addClass('tree-dnd-yes');
                    $(this).css('border-left', '1px solid #ff0000');
                },
                onDragLeave: function (e, source) {
                    $(source).draggable('proxy').removeClass('tree-dnd-yes').addClass('tree-dnd-no');
                    $(this).css('border-left', 0);
                },
                onDrop: function (e, source) {
                    $(this).css('border-left', 0);
                    var fromField = $(source).attr('field');
                    var toField = $(this).attr('field');
                    setTimeout(function () {
                        moveField(fromField, toField);
                        $(target).datagrid();
                        $(target).datagrid('columnMoving');
                    }, 0);
                }
            });

            // move field to another location
            function moveField(from, to) {
                var columns = $(target).datagrid('options').columns;
                var cc = columns[0];
                var c = _remove(from);
                if (c) {
                    _insert(to, c);
                }

                function _remove(field) {
                    for (var i = 0; i < cc.length; i++) {
                        if (cc[i].field == field) {
                            var c = cc[i];
                            cc.splice(i, 1);
                            return c;
                        }
                    }
                    return null;
                }

                function _insert(field, c) {
                    var newcc = [];
                    for (var i = 0; i < cc.length; i++) {
                        if (cc[i].field == field) {
                            newcc.push(c);
                        }
                        newcc.push(cc[i]);
                    }
                    columns[0] = newcc;
                }
            }
        });
    }
});
/**
 *  datagrid行拖动 js 事件 （初始化的时候是一个table,不能为div）
 *    onLoadSuccess: function () {
            $(this).datagrid('enableDnd');   都可以移动
             $(this).datagrid('enableDnd',1);   一行可以移动
        }

 */
$.extend($.fn.datagrid.defaults, {
    dropAccept: 'tr.datagrid-row',
    dragSelection: false,
    dragDelay: 100,
    onBeforeDrag: function (row) {
    },	// return false to deny drag
    onStartDrag: function (row) {
    },
    onStopDrag: function (row) {
    },
    onDragEnter: function (targetRow, sourceRow) {
    },	// return false to deny drop
    onDragOver: function (targetRow, sourceRow) {
    },	// return false to deny drop
    onDragLeave: function (targetRow, sourceRow) {
    },
    onBeforeDrop: function (targetRow, sourceRow, point) {
    },
    onDrop: function (targetRow, sourceRow, point) {
    },	// point:'append','top','bottom'
});
$.extend($.fn.datagrid.methods, {
    _appendRows: function (jq, row) {
        return jq.each(function () {
            var dg = $(this);
            var rows = $.isArray(row) ? row : [row];
            $.map(rows, function (row) {
                dg.datagrid('appendRow', row).datagrid('enableDnd', dg.datagrid('getRows').length - 1);
            });
        });
    },
    _insertRows: function (jq, param) {
        return jq.each(function () {
            var dg = $(this);
            var index = param.index;
            var row = param.row;
            var rows = $.isArray(row) ? row : [row];
            $.map(rows, function (row, i) {
                dg.datagrid('insertRow', {
                    index: (index + i),
                    row: row
                }).datagrid('enableDnd', index + i);
            });
        });
    },
    _getRowIndexs: function (jq, row) {
        var dg = jq;
        var rows = $.isArray(row) ? row : [row];
        var indexs = $.map(rows, function (row) {
            return dg.datagrid('getRowIndex', row);
        });
        return $.grep(indexs, function (index) {
            if (index >= 0) {
                return true;
            }
        });
    },
    _deleteRows: function (jq, indexs) {
        return jq.each(function () {
            // sort desc
            indexs.sort(function (x, y) {
                if (parseInt(x) > parseInt(y)) {
                    return -1;
                } else {
                    return 1;
                }
            });
            for (var i = 0; i < indexs.length; i++) {
                $(this).datagrid('deleteRow', indexs[i]);
            }
        });
    },
    _setSelections: function (jq) {
        return jq.each(function () {
            var rows = $(this).datagrid('getRows');
            for (var i = 0; i < rows.length; i++) {
                if (rows[i]._selected) {
                    $(this).datagrid('selectRow', i);
                    rows[i]._selected = undefined;
                }
            }
        });
    },
    clearInsertingFlag: function (jq) {
        return jq.each(function () {
            var opts = $(this).datagrid('options');
            if (opts.insertingIndex >= 0) {
                var tr = opts.finder.getTr(this, opts.insertingIndex);
                tr.removeClass('datagrid-row-top datagrid-row-bottom');
                opts.insertingIndex = -1;
            }
        });
    }
});

var disabledDroppingRows = [];

function enableDroppable(aa) {
    $.map(aa, function (row) {
        $(row).droppable('enable');
    });
}

$.extend($.fn.datagrid.methods, {
    resetDroppable: function (jq) {
        return jq.each(function () {
            var c = $(this).datagrid('getPanel')[0];
            var my = [];
            var left = [];
            for (var i = 0; i < disabledDroppingRows.length; i++) {
                var t = disabledDroppingRows[i];
                var p = $(t).closest('div.datagrid-wrap');
                if (p.length && p[0] == c) {
                    my.push(t);
                } else {
                    left.push(t);
                }
            }
            disabledDroppingRows = left;
            enableDroppable(my);
        });
    },
    enableDnd: function (jq, index) {
        if (!$('#datagrid-dnd-style').length) {
            $('<style id="datagrid-dnd-style">' +
                '.datagrid-row-top>td{border-top:1px solid red}' +
                '.datagrid-row-bottom>td{border-bottom:1px solid red}' +
                '</style>'
            ).appendTo('head');
        }
        return jq.each(function () {
            var target = this;
            var state = $.data(this, 'datagrid');
            var dg = $(this);
            var opts = state.options;

            var draggableOptions = {
                disabled: false,
                revert: true,
                cursor: 'pointer',
                proxy: function (source) {
                    var p = $('<div style="z-index:9999999999999"></div>').appendTo('body');
                    var draggingRow = getDraggingRow(source);
                    var rows = $.isArray(draggingRow) ? draggingRow : [draggingRow];
                    $.map(rows, function (row, i) {
                        var index = dg.datagrid('getRowIndex', row);
                        var tr1 = opts.finder.getTr(target, index, 'body', 1);
                        var tr2 = opts.finder.getTr(target, index, 'body', 2);
                        tr2.clone().removeAttr('id').removeClass('droppable').appendTo(p);
                        tr1.clone().removeAttr('id').removeClass('droppable').find('td').insertBefore(p.find('tr:eq(' + i + ') td:first'));
                        $('<td><span class="tree-dnd-icon tree-dnd-no" style="position:static">&nbsp;</span></td>').insertBefore(p.find('tr:eq(' + i + ') td:first'));
                    });
                    p.find('td').css('vertical-align', 'middle');
                    p.hide();
                    return p;
                },
                deltaX: 15,
                deltaY: 15,
                delay: opts.dragDelay,
                onBeforeDrag: function (e) {
                    var draggingRow = getDraggingRow(this);
                    if (opts.onBeforeDrag.call(target, draggingRow) == false) {
                        return false;
                    }
                    if ($(e.target).parent().hasClass('datagrid-cell-check')) {
                        return false;
                    }
                    if (e.which != 1) {
                        return false;
                    }
                },
                onStartDrag: function () {
                    $(this).draggable('proxy').css({
                        left: -10000,
                        top: -10000
                    });
                    var draggingRow = getDraggingRow(this);
                    setValid(draggingRow, false);
                    state.draggingRow = draggingRow;
                    opts.onStartDrag.call(target, draggingRow);
                },
                onDrag: function (e) {
                    var x1 = e.pageX, y1 = e.pageY, x2 = e.data.startX, y2 = e.data.startY;
                    var d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
                    if (d > 3) {	// when drag a little distance, show the proxy object
                        $(this).draggable('proxy').show();
                        var tr = opts.finder.getTr(target, parseInt($(this).attr('datagrid-row-index')), 'body');
                        $.extend(e.data, {
                            startX: tr.offset().left,
                            startY: tr.offset().top,
                            offsetWidth: 0,
                            offsetHeight: 0
                        });
                    }
                    this.pageY = e.pageY;
                },
                onEndDrag: function (e) {
                    var dd = $(this).data('draggable').droppables.filter(function () {
                        var dropObj = $(this);
                        if (dropObj.droppable('options').disabled) {
                            return false;
                        }
                        if (dropObj.hasClass('datagrid-row') && !dropObj.hasClass('datagrid-row-over')) {
                            return false;
                        }
                        var p2 = dropObj.offset();
                        if (e.pageX > p2.left && e.pageX < p2.left + dropObj.outerWidth()
                            && e.pageY > p2.top && e.pageY < p2.top + dropObj.outerHeight()) {
                            return true;
                        } else {
                            return false;
                        }
                    });
                    var trs = dd.filter(function () {
                        return $(this).hasClass('datagrid-row');
                    });
                    if (trs.length) {
                        dd = trs;
                    }
                    $(this).data('draggable').droppables = dd;
                },
                onStopDrag: function () {
                    enableDroppable(disabledDroppingRows);
                    disabledDroppingRows = [];
                    setValid(state.draggingRow, true);
                    opts.onStopDrag.call(target, state.draggingRow);
                }
            };
            var droppableOptions = {
                disabled: false,
                accept: opts.dropAccept,
                onDragEnter: function (e, source) {
                    if ($(this).droppable('options').disabled) {
                        return;
                    }
                    var dTarget = getDataGridTarget(this);
                    var dOpts = $(dTarget).datagrid('options');
                    var tr = dOpts.finder.getTr(dTarget, null, 'highlight');
                    var sRow = getDraggingRow(source);
                    var dRow = getRow(this);
                    if (tr.length && dRow) {
                        cb();
                    }

                    function cb() {
                        if (opts.onDragEnter.call(target, dRow, sRow) == false) {
                            $(dTarget).datagrid('clearInsertingFlag');
                            tr.droppable('disable');
                            tr.each(function () {
                                disabledDroppingRows.push(this);
                            });
                        }
                    }
                },
                onDragOver: function (e, source) {
                    if ($(this).droppable('options').disabled) {
                        return;
                    }
                    if ($.inArray(this, disabledDroppingRows) >= 0) {
                        return;
                    }
                    var dTarget = getDataGridTarget(this);
                    var dOpts = $(dTarget).datagrid('options');
                    var tr = dOpts.finder.getTr(dTarget, null, 'highlight');
                    if (tr.length) {
                        if (!isValid(tr)) {
                            setProxyFlag(source, false);
                            return;
                        }
                    }
                    setProxyFlag(source, true);

                    var sRow = getDraggingRow(source);
                    var dRow = getRow(this);
                    if (tr.length) {
                        var pageY = source.pageY;
                        var top = tr.offset().top;
                        var bottom = tr.offset().top + tr.outerHeight();
                        $(dTarget).datagrid('clearInsertingFlag');
                        dOpts.insertingIndex = tr.attr('datagrid-row-index');
                        if (pageY > top + (bottom - top) / 2) {
                            tr.addClass('datagrid-row-bottom');
                        } else {
                            tr.addClass('datagrid-row-top');
                        }
                        if (dRow) {
                            cb();
                        }
                    }

                    function cb() {
                        if (opts.onDragOver.call(target, dRow, sRow) == false) {
                            setProxyFlag(source, false);
                            $(dTarget).datagrid('clearInsertingFlag');
                            tr.droppable('disable');
                            tr.each(function () {
                                disabledDroppingRows.push(this);
                            });
                        }
                    }
                },
                onDragLeave: function (e, source) {
                    if ($(this).droppable('options').disabled) {
                        return;
                    }
                    setProxyFlag(source, false);
                    var dTarget = getDataGridTarget(this);
                    $(dTarget).datagrid('clearInsertingFlag');
                    var sRow = getDraggingRow(source);
                    var dRow = getRow(this);
                    if (dRow) {
                        opts.onDragLeave.call(target, dRow, sRow);
                    }
                },
                onDrop: function (e, source) {
                    if ($(this).droppable('options').disabled) {
                        return;
                    }
                    var sTarget = getDataGridTarget(source);
                    var dTarget = getDataGridTarget(this);
                    var dOpts = $(dTarget).datagrid('options');
                    var tr = dOpts.finder.getTr(dTarget, null, 'highlight');

                    var point = null;
                    var sRow = getDraggingRow(source);
                    var dRow = null;
                    if (tr.length) {
                        if (!isValid(tr)) {
                            return;
                        }
                        point = tr.hasClass('datagrid-row-top') ? 'top' : 'bottom';
                        dRow = getRow(tr);
                    }

                    $(dTarget).datagrid('clearInsertingFlag');
                    if (opts.onBeforeDrop.call(target, dRow, sRow, point) == false) {
                        return;
                    }
                    insert.call(this);
                    opts.onDrop.call(target, dRow, sRow, point);

                    function insert() {
                        var destIndex = parseInt(tr.attr('datagrid-row-index'));

                        if (!point) {
                            var indexs = $(sTarget).datagrid('_getRowIndexs', sRow);
                            $(dTarget).datagrid('_appendRows', sRow);
                            $(sTarget).datagrid('_deleteRows', indexs);
                            $(dTarget).datagrid('_setSelections');
                        } else if (dTarget != sTarget) {
                            var index = point == 'top' ? destIndex : (destIndex + 1);
                            if (index >= 0) {
                                var indexs = $(sTarget).datagrid('_getRowIndexs', sRow);
                                $(dTarget).datagrid('_insertRows', {
                                    index: index,
                                    row: sRow
                                });
                                $(sTarget).datagrid('_deleteRows', indexs);
                                $(dTarget).datagrid('_setSelections');
                            }
                        } else {
                            var dg = $(dTarget);
                            var index = point == 'top' ? destIndex : (destIndex + 1);
                            if (index >= 0) {
                                var indexs = dg.datagrid('_getRowIndexs', sRow);
                                var destIndex = parseInt(tr.attr('datagrid-row-index'));
                                var index = point == 'top' ? destIndex : (destIndex + 1);
                                if (index >= 0) {
                                    dg.datagrid('_insertRows', {
                                        index: index,
                                        row: sRow
                                    });
                                    for (var i = 0; i < indexs.length; i++) {
                                        if (indexs[i] > index) {
                                            indexs[i] += indexs.length;
                                        }
                                    }
                                    dg.datagrid('_deleteRows', indexs);
                                    dg.datagrid('_setSelections');
                                }
                            }
                        }
                    }
                }
            }

            if (index != undefined) {
                var trs = opts.finder.getTr(this, index);
            } else {
                var trs = opts.finder.getTr(this, 0, 'allbody');
            }
            trs.draggable(draggableOptions);
            trs.droppable(droppableOptions);
            setDroppable(target);

            function setProxyFlag(source, allowed) {
                var icon = $(source).draggable('proxy').find('span.tree-dnd-icon');
                icon.removeClass('tree-dnd-yes tree-dnd-no').addClass(allowed ? 'tree-dnd-yes' : 'tree-dnd-no');
            }

            function getRow(tr) {
                if (!$(tr).hasClass('datagrid-row')) {
                    return null
                }
                var target = $(tr).closest('div.datagrid-view').children('table')[0];
                var opts = $(target).datagrid('options');
                return opts.finder.getRow(target, $(tr));
            }

            function getDraggingRow(tr) {
                if (!$(tr).hasClass('datagrid-row')) {
                    return null
                }
                var target = getDataGridTarget(tr);
                var opts = $(target).datagrid('options');
                var rows = $(target).datagrid('getRows');
                for (var i = 0; i < rows.length; i++) {
                    rows[i]._selected = undefined;
                }
                if (opts.dragSelection) {
                    if ($(tr).hasClass('datagrid-row-selected')) {
                        var rows = $(target).datagrid('getSelections');
                        $.map(rows, function (row) {
                            row._selected = true;
                        });
                        return rows;
                    }
                }
                var row = opts.finder.getRow(target, $(tr));
                row._selected = $(tr).hasClass('datagrid-row-selected');
                return row;
            }

            function setDroppable(target) {
                getDroppableBody(target).droppable(droppableOptions).droppable('enable');
            }

            function getDataGridTarget(el) {
                return $(el).closest('div.datagrid-view').children('table')[0];
            }

            function getDroppableBody(target) {
                var dc = $(target).data('datagrid').dc;
                return dc.view;
            }

            function isValid(tr) {
                var opts = $(tr).droppable('options');
                if (opts.disabled || opts.accept == 'no-accept') {
                    return false;
                } else {
                    return true;
                }
            }

            function setValid(rows, valid) {
                var accept = valid ? opts.dropAccept : 'no-accept';
                $.map($.isArray(rows) ? rows : [rows], function (row) {
                    var index = $(target).datagrid('getRowIndex', row);
                    opts.finder.getTr(target, index).droppable({accept: accept});
                });
            }
        });
    },
    disableDnd: function (jq) {
        return jq.each(function () {
            var target = this;
            var state = $.data(this, 'datagrid');
            var dg = $(this);
            var opts = state.options;
            var trs = opts.finder.getTr(this, 0, 'allbody');
            trs.draggable('disable');
            trs.droppable('disable');
        });
    }

});
